<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>title</title>
    <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" name="viewport" />
    <style>
      body,
      p,
      ol,
      ul,
      li,
      dl,
      dd,
      h1,
      h2,
      h3,
      h4,
      h5,
      h6,
      input,
      iframe,
      nav,
      header,
      footer {
        margin: 0;
        padding: 0;
        list-style: none;
      }
      body {
        font-size: 14px;
        font-family: -apple-system, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Arial, sans-serif;
        color: #27282b;
        background: #fff;
      }
      a {
        text-decoration: none;
        color: #27282b;
      }
      *,
      *::before,
      *::after {
        outline: none;
        box-sizing: border-box;
      }
      html,
      body {
        height: 100%;
      }
      .d1 {
        width: 50%;
        height: 100px;
        background: #eee;
        margin: 50px auto;
      }
    </style>
  </head>

  <body>
    <div class="wrapper" id="app">
      <div class="d1" @click="myClick">节流1</div>
      <div class="d1" @click="myClick1">节流2</div>
      <div class="d1" @click="myClick_0">防抖1</div>
      <div class="d1" @click="myClick_1">防抖2</div>
    </div>

    <script src="https://lib.baomitu.com/vue/2.5.21/vue.min.js"></script>
    <script>
      var vm = new Vue({
        el: '#app',
        data() {
          return {
            text: '节流',
            text2: '防抖',
            con: null,
            myThr: null
          }
        },
        created() {
          this.myCon = this.myDebounce(this.conso2, 1000);
          this.myThr = this.myThrottle(this.conso, 1000);
        },
        methods: {
          conso() {
            console.log('节流');
            console.log(arguments[0]);
          },
          conso2() {
            console.log('防抖');
          },
          myClick() {
            throttle_1(+new Date(), this.conso, null)
          },
          myClick1() {
            this.myThr('throttle');
          },
          myClick_0: debounce(function() {
            console.log(this)
            console.log('1-----1')
            vm.conso2()
          }, 1000, {a: 'the ctx is oject'}),
          myClick_1() {
            this.myCon();
          },
          myDebounce(fn, delay, ctx) {
            let timer = null;
            return function() {
              timer && clearTimeout(timer);
              timer = setTimeout(() => {
                fn.apply(ctx, arguments);
              }, delay);
            }
          },
          //时间戳方式
          myThrottle(fn, delay, ctx) {
            let time = 0;
            return function() {
              let curT = new Date();
              if (curT - time > delay) {
                fn.apply(ctx, arguments);
                time = curT;
              }
            }
          },
          //定时器方式
          throttle(fn, delayTime) {
            let flag;
            return function() {
              let ctx = this;
              let args = arguments;
              if (!flag) {
                flag = setTimeout(() => {
                  fn.apply(ctx, args);
                  flag = false;
                }, delayTime);
              }
            }
          },
          // requestAnimationFrame
          throttle(fn, delayTime) {
            let flag;
            return function() {
              let ctx = this;
              let args = arguments;
              if (!flag) {
                requestAnimationFrame(() => {
                  fn.apply(ctx, args);
                  flag = false;
                });
                flag = true;
              }
            }
          },
          //
          throttle(fn, delayTime) {
            let flag;
            let start = Date.now();
            return function () {
              let content = this;
              let args = arguments;
              let now = Date.now();
              let remainTime = delayTime - (now - start);
              if (remainTime < 0) {
                fn.apply(content, args);
              } else {
                setTimeout(() => {
                  fn.apply(this, args)
                }, remainTime);
              }
            }
          }
        },
      })

      function debounce(method, delay, ctx) {
        var timer = null
        return function() {
          timer && clearTimeout(timer)
          timer = setTimeout(() => {
            method.apply(ctx, arguments)
          }, delay)
        }
      }

      //节流函数
      function throttle_1(now, method, context) {
        var time = +new Date()
        throttle_1 = function(now, method, context) {
          if (now - time > 1000) {
            time = now // 更新time
            method.call(context)
          }
        }
        throttle_1(now, method, context)
      }

      function resize() {
        console.log(1)
      }
      // window.onresize = function() {
      //   throttle_1(+new Date(), resize, null)
      // }
    </script>
  </body>
</html>
